package org.innovasix.educational.javap.domain.constantpool;

import java.util.ArrayList;
import java.util.List;

import org.innovasix.educational.javap.domain.datatypes.cp_info;
import org.innovasix.educational.javap.domain.datatypes.u1;
import org.innovasix.educational.javap.domain.datatypes.u2;
import org.innovasix.educational.javap.domain.parser.ByteQueue;

/**
 * <p>
 * <b><i>From the JVM specification:</i></b><br/>
 * The CONSTANT_Utf8_info structure is used to represent constant string values.
 * </p>
 * 
 * @see <a
 *      href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.1">4.4.1.
 *      The CONSTANT_Class_info Structure</a>
 * 
 * @author sven.mentl@gmail.com
 * 
 */
public class CONSTANT_Utf8_info extends cp_info {

	/**
	 * <p>
	 * <b><i>From the JVM specification:</i></b><br/>
	 * The tag item has the value CONSTANT_UTtf8(1).
	 * </p>
	 */
	final u1 tag = new u1(ConstantPoolTags.CONSTANT_Utf8.decimalValue());

	/**
	 * <p>
	 * <b><i>From the JVM specification:</i></b><br/>
	 * The value of the length item gives the number of bytes in the bytes array.
	 * The strings in the CONSTANT_Utf8_info structure are not null-terminated.
	 */
	u2 length;
	
	/**
	 * <p>
	 * <b><i>From the JVM specification:</i></b><br/>
	 * The bytes array contains the bytes of the string. 
	 * No byte may have the value 0 or lie in the range 0xf0 - 0xff
	 */
	u1[] bytes;

	public CONSTANT_Utf8_info(ByteQueue byteQueue) {
		
		length = byteQueue.pollTwoBytes("CONSTANT_Utf8_info");
		
		List<u1> byteaList = new ArrayList<u1>();
		
		for(int i = 0; i < length.getValue(); i++){
			byteaList.add(byteQueue.pollOneByte("CONSTANT_Utf8_info"));
		}
		
		bytes = byteaList.toArray(new u1[0]);
		
		for(u1 b : bytes){
			System.out.print((char) b.getValue());
		}
		
		System.out.println();
	}

	public String toString(){
		StringBuilder sb = new StringBuilder();
		sb.append("CONSTANT_Utf8_info [");
		sb.append("length: ");
		sb.append(length);
		sb.append(" bytes: ");
		sb.append("0x");
		for(u1 currentByte : bytes)
			sb.append(currentByte.toString().substring(2));
		sb.append(" \"");
		for(u1 b : bytes){
			sb.append((char) b.getValue());
		}
		sb.append("\"]");
		return sb.toString();
	}

}
